package skewreduce.framework.planner.search;

import java.util.SortedSet;
import java.util.TreeSet;

import org.apache.hadoop.conf.Configuration;

import skewreduce.framework.planner.PartitionNode;
import skewreduce.framework.planner.PriorityScheduler;


public class GreedyGlobalSchedule extends SearchStrategy {
	PriorityScheduler scheduler;
	SortedSet<PartitionNode> currentPlan = new TreeSet<PartitionNode>(); // for scheduler
	double bestCost;
	int numMachines;

	@Override
	public void init(PartitionNode root) {
		currentPlan.add(root);
		bestCost = root.getWorkSecs();
	}

	@Override
	public void reset() {
		currentPlan.clear();
		bestCost = Double.MAX_VALUE;
	}
	
	@Override
	public boolean shouldPartition(PartitionNode p, PartitionNode l, PartitionNode r,boolean force) {
		scheduler.reset(currentPlan);
		scheduler.add(l);
		scheduler.add(r);
		double schedCost = scheduler.estimateSchedule();
		
		if ( LOG.isDebugEnabled() ) {
			LOG.debug("best cost = {}, current = {}",bestCost,schedCost);
		}
		
		boolean isGood = schedCost < bestCost || force;
		
		if ( isGood ) {
			bestCost = schedCost;
			if ( LOG.isDebugEnabled() ) {
				LOG.debug("Machine {}: partition {} - forced = {}, total cost = {}",new Object[] { numMachines, p.getPartition().toSpec(), force, bestCost });
			}

			// add two split nodes to leaves and insert to the queue
			currentPlan.add(l);
			currentPlan.add(r);
		}
		
		return isGood;
	}

	@Override
	public Configuration getConf() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void setConf(Configuration conf) {
		scheduler = new PriorityScheduler(conf);
	}

	@Override
	public void setNumMachines(int n) {
		this.numMachines = n;
		scheduler.setNumSlots(n);
	}
}
